#include "include/shortcutsmodel.h"
#include "include/customshortcut.h"
#include "include/customshortcut_qmeta.h"

namespace
{

	const char* NullShortcut = "<null>";

	const char* NameHeader = "command";
	const char* ShortcutHeader = "shortcut";


	QString removeAmpersand(QString s)
	{
		return s.remove('&');
	}


} //private namespace



ShortcutsModel::ShortcutsModel(QObject *parent) :
	QAbstractTableModel(parent), _shortcuts(0)
{
}

QModelIndex ShortcutsModel::parent(const QModelIndex &) const
{
	return QModelIndex();
}

QVariant ShortcutsModel::data(const QModelIndex &index, int role) const
{
	Qt::ItemDataRole itemDataRole = (Qt::ItemDataRole)role;
	switch (itemDataRole)
	{
	case Qt::DisplayRole:
		return displayRoleData(index);
	case Qt::EditRole:
		return editRoleData(index);
	case Qt::TextAlignmentRole:
		return textAlignmentData(index);

	default:
		return QVariant();
	}
}


int ShortcutsModel::rowCount(const QModelIndex &parent) const
{
	if (parent.isValid())
		return 0;

	return _shortcuts != 0 ? _shortcuts->size() : 0;
}


int ShortcutsModel::columnCount(const QModelIndex &) const
{
	return 2;
}

void ShortcutsModel::setShortcuts(MuCustomShortcuts* value)
{
	if (_shortcuts == value)
		return;

//	beginResetModel();
	_shortcuts = value;
	_transientData.clear();
//	endResetModel();
}


QVariant ShortcutsModel::displayRoleData(const QModelIndex& index) const
{
	if (_shortcuts == 0 || !index.isValid()
	        || index.row() < 0 || index.row() >= (int)_shortcuts->size())
		return QVariant();

	CustomShortcut* shortcut = (*_shortcuts)[index.row()];

	if (index.column() == NameColumn)
		return shortcut != 0 ? removeAmpersand(shortcut->text()) : tr(NullShortcut);

	if (index.column() == ShortcutColumn && shortcut != 0)
	{
		TransientDataStorage::const_iterator it = _transientData.find(shortcut->tag());
		QKeySequence currentShortcut = it != _transientData.end() ? (*it).second : shortcut->sequence();
		return QVariant(currentShortcut.toString());
	}

	return QVariant();
}


QVariant ShortcutsModel::editRoleData(const QModelIndex& index) const
{
	if (_shortcuts == 0 || !index.isValid()
	        || index.column() != ShortcutColumn
	        || index.row() < 0 || index.row() >= (int)_shortcuts->size())
		return QVariant();

	CustomShortcut* shortcut = (*_shortcuts)[index.row()];

	QMap<QString, QVariant> map;
	ShortcutsMetaHelper::setDefaultShortcut(map, shortcut->defaultSequence());

	TransientDataStorage::const_iterator it = _transientData.find(shortcut->tag());
	QKeySequence currentShortcut = it != _transientData.end() ? (*it).second : shortcut->sequence();
	ShortcutsMetaHelper::setCurrentShortcut(map, currentShortcut);

	return QVariant(map);
}


QVariant ShortcutsModel::textAlignmentData(const QModelIndex& index) const
{
	if (!index.isValid())
		return QVariant();

	return QVariant(Qt::AlignCenter);
}


QVariant ShortcutsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
	Qt::ItemDataRole headerDataRole = (Qt::ItemDataRole)role;

	switch (headerDataRole)
	{

	case Qt::DisplayRole:
	{
		if (section == NameColumn && orientation == Qt::Horizontal)
			return tr(NameHeader);
		if (section == ShortcutColumn && orientation == Qt::Horizontal)
			return tr(ShortcutHeader);
	}
	default:
		return QVariant();

	} //switch

	return QVariant();
}

Qt::ItemFlags ShortcutsModel::flags(const QModelIndex &index) const
{
	if (index.isValid() && index.column() == ShortcutColumn)
		return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;

	return QAbstractTableModel::flags(index);
}


bool ShortcutsModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
	if (!index.isValid() || index.column() != ShortcutColumn || role != Qt::EditRole)
		return false;

	CustomShortcut* shortcut = (*_shortcuts)[index.row()];
	if (shortcut == 0)
		return false;

	QMap<QString, QVariant> map = value.toMap();


	QKeySequence currentSequence = ShortcutsMetaHelper::getCurrentShortcut(map);

	if (_transientData.find(shortcut->tag()) != _transientData.end())
	{
		_transientData[shortcut->tag()] = currentSequence;
		return true;
	}
	else if (currentSequence != shortcut->sequence())
	{
		_transientData[shortcut->tag()] = currentSequence;
		return true;
	}

	return false;
}


void ShortcutsModel::applyChanges()
{
	if (_shortcuts == 0)
		return;

	foreach (TransientDataStorage::value_type p, _transientData)
	_shortcuts->setSequence(p.first, p.second);

	_shortcuts->saveToSettings();
}


